23.6 Drucken von Grafiken
 
Wir müssen uns nun ansehen, in welcher Beziehung Maßeinheiten der Bildschirmausgabe mit denen der Druckerausgabe stehen. Dazu verwenden wir ein einfaches Programm, das auch dem Monitor ein Quadrat von 100 x 100 Einheiten ausgibt und dieses auf Anklicken einer Schaltfläche hin auch ausdruckt.
| ...
|
| private void pictureBox1_Paint(object sender, PaintEventArgs e) {
|
| Graphics g = e.Graphics;
|
| Pen pen = new Pen(Brushes.Black);
|
| g.DrawRectangle(pen, 10, 10, 100, 100);
|
| }
|
| private void printDocument1_PrintPage(object sender, PrintPageEventArgs e) {
|
| Graphics g = e.Graphics;
|
| Pen pen = new Pen(Brushes.Black);
|
| g.DrawRectangle(pen, g.VisibleClipBounds.X,
|
| g.VisibleClipBounds.Y, 100, 100);
|
| }
|
Sie werden feststellen, dass die beiden Quadrate unterschiedlich groß sind. Messen Sie die Kantenlänge des ausgedruckten nach – es sind allseitig 25,4 mm. Wie groß die Kantenlänge auf dem Bildschirm ist, kann nicht mit derselben Selbstsicherheit vorhergesagt werden, denn es spielen einige beeinflussende Faktoren dabei eine Rolle.
Die unterschiedlichen Abmessungen der beiden Quadrate lassen sich auf verschiedene Einheiten zurückführen, die den beiden Graphics-Objekten zugrunde liegen. Die Koordinatenwerte, die an die Zeichenfunktionen des Graphics-Objekts des PrintPage-Ereignisses übergeben werden, werden standardmäßig in Einheiten von 1/100 Zoll interpretiert. Das entspricht der Einstellung der Eigenschaft PageUnit=GraphicsUnit.Display. Die 100 Einheiten, die wir im Beispiel oben zur Festlegung der Kantenlänge angegeben haben, führen deshalb zu einer Ausgabe, die exakt ein Zoll ist. (Sie können das nachmessen.) War die Ausgabe der Grafik basierend auf diesem Maßsystem beabsichtigt, brauchen wir uns keine weiteren Gedanken zu machen. Stand hinter der Kantenlänge von 100 Einheiten jedoch die Absicht, ein Quadrat von 100 mm zu zeichnen, müssen wir die Druckausgabe noch an das metrische System anpassen.
Die Bildschirmausgabe bedient sich anderer Einheiten – es sind standardmäßig Pixel. Die PageUnit-Eigenschaft des Graphics-Objekt des Paint-Ereignisses ist demnach auf GraphicsUnit.Pixel eingestellt. Wie sich das auf die Bildschirmdarstellung auswirkt, lässt sich nicht allgemein gültig vorhersagen. Es spielt dabei nicht nur der Videomodus (Auflösung) eine Rolle, auch jeder Monitor und dessen individuelle Einstellung beeinflussen die Größe der Anzeige nachhaltig.
23.6.1 Festlegung der Einheiten und Skalierung
 
In Kapitel 22.2.5 haben wir uns bereits die Eigenschaft PageUnit des Graphics-Objekts und ihre Auswirkungen auf die Darstellung geometrischer Figuren angesehen. Wir können diese Eigenschaft auch für unsere Druckausgabe so einstellen, dass uns das geometrische Objekt wunschgemäß zu Papier gebracht wird. Nehmen wir an, dass unser Quadrat eine Kantenlänge von 100 mm aufweisen soll, müssten wir im PrintPage-Ereignis die folgende Anweisung ergänzen:
| e.Graphics.PageUnit = GraphicsUnit.Millimeter ;
|
Die Maßangaben werden jetzt nicht mehr als 1/100 Zoll interpretiert, sondern je Einheit mit einem Millimeter. Die Folge ist, dass das Quadrat mit einer Kantenlänge von 100 mm ausgedruckt wird, während sich die Grafikausgabe auf dem Bildschirm unbeeindruckt zeigt – zumindest solange wir im Paint-Ereignis keine Änderung der Einheiten vornehmen.
Es wäre natürlich auch denkbar, dass wir deutlich größere Figuren ausdrucken lassen wollen. Stellen Sie sich dazu vor, das zu zeichnende Quadrat würde die Abbildung des Grundstücks eines Hauseigentümers sein – 100 x 100 m2
beziehungsweise 100000 x 100000 mm2
. Sie sind also gezwungen, die Maße so zu skalieren, dass sie noch auf das Druckpapier passen. Dazu können Sie den unbequemen Weg gehen und die Maße bereits vor der Eingabe skalieren, oder Sie erinnern sich, dass mit der Eigenschaft PageScale vom Graphics-Objekt eine entsprechende Möglichkeit angeboten wird.
Mit
| e.Graphics.PageUnit = GraphicsUnit.Millimeter ;
|
| e.Graphics.PageScale = 0.001 ;
|
erhalten Sie wieder ein Rechteck (hier: Quadrat), das mit einer Kantenlänge von exakt 100 mm ausgedruckt wird – sofern Sie das Graphics-Objekt im PrintPage-Ereignis so festlegen.
23.6.2 Beispielprogramm zum Drucken einer Grafik
 
Im folgenden Beispiel wird ein Quadrat in einer Picturebox in Pixeleinheiten angezeigt und mit einer Seitenlänge von 100 mm auf dem Drucker ausgedruckt. Innerhalb des Quadrats beschreibt darüber hinaus eine Zeichenfolge die Größe des geometrischen Objekts.
| // --------------------------------------------------------------
|
| // Beispiel: ...\Kapitel 23\QuadratDrucken
|
| // --------------------------------------------------------------
|
| ...
|
| private void pictureBox1_Paint(object sender, PaintEventArgs e) {
|
| Graphics g = e.Graphics;
|
| Color color = Color.Black;
|
| Font font = new Font("Arial",8);
|
| this.Draw(g, font, color, 10, 10, 100, 100);
|
| }
|
|
|
| private void printDocument1_PrintPage(object sender, PrintPageEventArgs e) {
|
| Graphics g = e.Graphics;
|
| Font font = new Font("Arial",8);
|
| g.PageUnit = GraphicsUnit.Millimeter;
|
| g.PageScale = 1F;
|
| Color color = Color.Black;
|
| this.Draw(g, font, color, (int)(e.MarginBounds.X *
|
| 0.254),(int)(e.MarginBounds.Y * 0.254), 100,100);
|
| }
|
| // benutzerdefinierte Zeichenroutine
|
| private void Draw(Graphics g, Font font, Color color, int XStart,
|
| int YStart, int width, int height) {
|
| g.DrawRectangle(new Pen(color), XStart, YStart, width, height);
|
| g.DrawString("Größe: 100x100",font, new SolidBrush(color),
|
| new Point(XStart + 2, YStart + 2));
|
| }
|
| private void btnDrucken_Click(object sender, EventArgs e) {
|
| printDocument1.Print();
|
| }
|
Da die beiden Methoden DrawString und DrawRectangle sowohl zur Anzeige in der Picturebox als auch zur Ausgabe des Druckers aufgerufen werden, bietet es sich an, dafür eine benutzerdefinierte Zeichenroutine bereitzustellen, die aus den beiden Ereignishandlern aufgerufen wird. Den Parametern der Routine Draw werden alle erforderlichen Daten übergeben, die zum Zeichnen des Rechtecks und zur Ausgabe der Zeichenfolge erforderlich sind.
Die Kantenlänge des Quadrats beträgt 100 Einheiten. Im Paint-Ereignishandler führt das bei einer Bildschirmauflösung von 1024 x 768 zu einer akzeptablen Darstellung. Daher ist auch nicht notwendig, hier eine Skalierung vorzunehmen. Da wir aber die Druckausgabe des Quadrats im Maßstab 1:1 anstreben, muss das Graphics-Objekt des PrintPage-Ereignishandlers entsprechend konfiguriert werden:
| g.PageUnit = GraphicsUnit.Millimeter;
|
| g.PageScale = 1F;
|
Die Festlegung der Eigenschaft PageScale wäre eigentlich nicht notwendig, erlaubt uns andererseits, mit dieser Eigenschaft zu experimentieren.
Beim Aufruf der Routine müssen wir aufpassen. Im dritten und vierten Parameter erwartet Draw die Koordinaten x und y für den Startpunkt des auszudruckenden Quadrats. Weil das herkömmliche Format DIN A4 des Druckerpapiers genügend Raum für unser Quadrat lässt, können wir, durchaus ohne Einschränkungen in Kauf nehmen zu müssen, die von MarginBounds zurückgegebenen Abmessungen nutzen. MarginBounds liefert aber nur »Einheiten«, nämlich genau 100. Als 1/100 Zoll interpretiert bedeutet das einen Seitenrand von 25,4 mm (plus des obligatorischen außerhalb des Druckbereichs liegenden Rands). Da wir aber auf GraphicsUnit.Millimeter umgeschaltet haben, werden diese Einheiten als Millimeter interpretiert und würden zu einem Randabstand des Quadrats von über 10 cm führen. Damit die Einheiten richtig interpretiert werden, müssen wir den Wert von MarginBounds mit 0,254 multiplizieren:
Die Linienbreite des Zeichenstifts
Hinsichtlich der Linienbreite der Druckausgabe können wir uns ein Problem einhandeln. Im Beispiel QuadratDrucken sieht die Definition des Pen-Objekts für den Aufruf der DrawRectangle-Methode wie folgt aus:
Da wir keine Stiftbreite angegeben haben, beträgt diese standardmäßig 1. Die Bildschirmausgabe interpretiert das als 1 Pixel, zur Druckausgabe wird zur Interpretation die eingestellte Einheit herangezogen. Wir hatten GraphicsUnit.Millimeter eingestellt, also werden die Linien 1 mm breit gezeichnet. Wünschen wir eine andere Linienbreite, müssen wir das schon beim Konstruktoraufruf berücksichtigen. Beispielsweise wird die folgende Anweisung im Programmbeispiel zu einer Strichbreite von 0,5 mm führen:
Die Schriftgröße der Druckausgabe
Die Größe einer Schrift bei der Druckausgabe orientiert sich nicht an den Einstellungen der Eigenschaften PageScale und PageUnit. Ausschlaggebend ist vielmehr die Schriftgröße, die in Punkteinheiten angegeben ist. Ein Punkt ist ziemlich genau mit 1/72 Zoll gleichzusetzen, was 0,138 Zoll entspricht. Im Beispielprogramm oben wurde die Größe der Schrift mit 8 Punkten festgelegt, also ca. 0,11 Zoll bzw. 2,8 mm.
Wenn Ihnen die Umrechnung zu aufwändig ist, können Sie auch zwei andere Konstruktoren der Font-Klasse benutzen, die neben der Angabe der Schriftfamilie (bzw. der Schriftart als Zeichenfolge) und der Schriftgröße auch einen weiteren Parameter vom Typ GraphicUnit bereitstellen:
| public Font(string, float, GraphicsUnit);
|
| public Font(FontFamily, float, GraphicsUnit);
|
| public Font(string, float, FontStyle, GraphicsUnit);
|
| public Font(FontFamily, float, FontStyle, GraphicsUnit);
|
Mit
| Font font = new Font("Arial", 8, GraphicsUnit.Millimeter);
|
wird die Höhe einer auf diesem Font basierenden Zeichenfolge genau 8 mm betragen. Sie können auch zur Bildschirmausgabe eine von Punkt abweichende Maßeinheit angeben, sollten dabei jedoch berücksichtigen, dass die tatsächliche Höhe auf dem Monitor auch vom Monitor und seinen Einstellungen abhängt. |